package org.prophet.accessexcel.utility;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;

/**
 * @Description: 反射工具类
 * @author: april
 * @date: 2020年10月12日 20:01
 */
public class ReflectUtils {
    /**
     * 根据属性，触发get方法，并获取get方法额返回值
     * @param obj
     * @param name
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static Object getInvoke4GetMethod(Object obj, String name) throws InvocationTargetException, IllegalAccessException {
        Method[] m = obj.getClass().getMethods();
        for (int i = 0; i < m.length; i++) {
            if (("get" + name).toLowerCase().equals(m[i].getName().toLowerCase())) {
                return m[i].invoke(obj);
            }
        }
        return null;
    }

    /**
     * 根据属性，拿到set方法，并把值set到对象中
     *
     * @param obj       对象
     * @param clazz     对象的class
     * @param fieldName 属性名
     * @param typeClass 属性类型
     * @param value     需要设置的属性值
     */
    //setValue(person2, person2.getClass(), field2, Person.class.getDeclaredField(field2).getType(), value);
    public static void setValue(Object obj, Class<?> clazz, String fieldName, Class<?> typeClass, Object value) {
        fieldName = removeUnderline(fieldName);
        String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        try {
            Method method = clazz.getDeclaredMethod(methodName, new Class[]{typeClass});
            method.invoke(obj, new Object[]{getClassTypeValue(typeClass, value)});
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public static <T> Class<?> getFieldTypeClass(T t,String fieldName) throws NoSuchFieldException {
        return t.getClass().getDeclaredField(fieldName).getType();
    }

    /**
     * 处理字符串,去除下划线
     *
     * @param str
     * @return
     */
    public static String removeUnderline(String str) {
        if (null != str && str.contains("_")) {
            int i = str.indexOf("_");
            char ch = str.charAt(i + 1);
            //转驼峰
            char newCh = (ch + "").substring(0, 1).toUpperCase().toCharArray()[0];
            String newStr = str.replace(str.charAt(i + 1), newCh);
            String newStr2 = newStr.replace("_", "");
            return newStr2;
        }
        return str;
    }


    /**
     * 通过class类型获取获取对应类型的值
     *
     * @param typeClass class类型
     * @param value     值
     * @return Object
     */
    private static Object getClassTypeValue(Class<?> typeClass, Object value) {
        if (typeClass == int.class || value instanceof Integer) {
            if (null == value) {
                return 0;
            }
            return value;
        } else if (typeClass == short.class) {
            if (null == value) {
                return 0;
            }
            return value;
        } else if (typeClass == byte.class) {
            if (null == value) {
                return 0;
            }
            return value;
        } else if (typeClass == double.class) {
            if (null == value) {
                return 0;
            }
            return value;
        } else if (typeClass == long.class) {
            if (null == value) {
                return 0;
            }
            return value;
        } else if (typeClass == String.class) {
            if (null == value) {
                return "";
            }
            return value;
        } else if (typeClass == boolean.class) {
            if (null == value) {
                return true;
            }
            return value;
        } else if (typeClass == BigDecimal.class) {
            if (null == value) {
                return new BigDecimal(0);
            }
            return new BigDecimal(value + "");
        } else {
            return typeClass.cast(value);
        }
    }

}
